/*

Stickman Adventure - a game created by Daco & his cousin

Copyright (C) 2011-2012  DacoTaco & Wouterke

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation version 2.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


*/
#include <SDL.h> 
#include <SDL_video.h>
#include <SDL_image.h>
#include "SDL_rotozoom.h"
#include <SDL_mixer.h>

#ifdef _WIN32

#include <SDL_getenv.h>

#endif

#ifdef OGL_MODE

#include "SDL_opengl.h"

#endif

#include "Global.h"
#include "Vegeta.h"
#include "Timer.h"
#include "Player.h"
#include "StaticObject.h"
#include "Screen.h"
#include "map_file.h"
#include "Object_collection.h"
#include "extern.h"
#include "Enemy.h"


//The music that will be played 
Mix_Music *music = NULL; 
Screen* screen;

#define UPDATE_FREQUENCY 128

int InitSDL(void)
{
	#ifdef _WIN32		
	//SDL_putenv("SDL_VIDEODRIVER=directx");
	/*char* sBuffer = new char[256];
	sBuffer = SDL_getenv("SDL_VIDEO_CENTERED");
	printf("SDL_VIDEODRIVER is %s\n",sBuffer);
	delete sBuffer;*/
	#endif	
	SDL_putenv("SDL_VIDEO_CENTERED=center"); //center game window
	return SDL_Init( SDL_INIT_EVERYTHING ); 
}
int main( int argc, char* args[] ) 
{

	
	//variables
	SDL_Event event;
	bool quit = false;
	//Whether or not to cap the frame rate 
	bool cap = true; 
	//The frame rate regulator 
	Timer fps;

	//Start SDL
	InitSDL();

	//create screen
	screen = new Screen(0,0,600,800,32);
	Collector.AddObject(screen);

	if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) 
		return 7;

	gprintf("read map returned %d\n",ReadMap("lol.map"));
	
	Static_Object* background = new Static_Object("wp_hit_it.png",0,0,960,1280,OBJECT_BACKGROUND,0);
	Static_Object* map_size = new Static_Object(NULL,0,0,map_x,map_y,OBJECT_BACKGROUND,0);
	//init vegeta's 
	Foo* Vegeta = new Foo("Vegeta_dance.png",(int)(background->getWidth()/1.488372)-(123/2),(int)(background->getHeight()/2.742857)-154); //Vegeta.SetCoordinates(1.488372,2.742857);
	Foo* Vegeta2 = new Foo("Vegeta_dance.png",(int)(background->getWidth()/2.370370)-(123/2),(int)(background->getHeight()/1.352112)-154); //Vegeta2.SetCoordinates(2.370370,1.352112);
	
	const char* en_sound[]={"enemy_plop.wav\0"};
	Enemy* Bewegende_Pinnen = new Enemy("en_spike_box.png",(background->getWidth()/2)+32,610-144,64,64,en_sound,1);
	Collector.AddObject(Bewegende_Pinnen);

	const char* sound[]={"jump.wav\0","death.wav\0"};
	Player* p1 = new Player("foo.png",(background->getWidth()/2)-48,610-144,sound,2);
	/*Player* p2 = new Player("foo.png",(background->getWidth()/2)-44,610-140,sound,2);
	short controlsP2[4];
	controlsP2[0] = SDLK_d;
	controlsP2[1] = SDLK_a;
	controlsP2[2] = SDLK_w;
	controlsP2[3] = SDLK_s;
	p2->SetControls(controlsP2);
	Collector.AddObject(p2);*/
	Collector.AddObject(map_size);
	Collector.AddObject(background);
	Collector.AddObject(p1);
	
	Collector.AddObject(Vegeta);
	Collector.AddObject(Vegeta2);
	
	//Update Screen 
	//Pause & update
	bool resize = false;

	//load & add platform objects to the collector

	//Static_Object(SDL_Surface *spritesheet,int xpos , int ypos, int h , int w ,char Tile_image);
	//(const char* spritesheet,int xpos , int ypos, int h , int w,char type,char Tile_image)
	Static_Object* floor = new Static_Object("text_block2.png",500,610,32,1410,1);
	//Static_Object* top = new Static_Object("text_block2.png",980,460,32,512,1); //top on the right
	//Static_Object* Spike = new Static_Object("text_spike.png",756,578,32,64,OBJECT_ENEMY,1);
	Static_Object* top2 = new Static_Object("text_block2.png",390,360,32,128,1); //top on the left

	Collector.AddObject(floor);
	//Collector.AddObject(top);
	Collector.AddObject(top2);
	if(map_file.size() > 0)
	{
		gprintf("map is %dx%d\nlatest entry is '%s' @ %dx%d and is %dx%d , type %d and uses '%s'\n",	map_x,map_y,
																								map_file.at(map_file.size()-1).entry_desc.c_str(),
																								map_file.at(map_file.size()-1).x,map_file.at(map_file.size()-1).y,
																								map_file.at(map_file.size()-1).h,map_file.at(map_file.size()-1).w,
																								map_file.at(map_file.size()-1).type, map_file.at(map_file.size()-1).texture_name.c_str());
		for(int x = 0;(unsigned int)x < map_file.size();x++)
		{
			//(const char* spritesheet,int xpos , int ypos, int h , int w ,char Tile_image);
			//(const char* spritesheet,int xpos , int ypos, int h , int w,char type,char Tile_image)
			Static_Object* pObject = new Static_Object(
				map_file.at(x).texture_name.c_str(),
				map_file.at(x).x,
				map_file.at(x).y,
				map_file.at(x).h,
				map_file.at(x).w,map_file.at(x).type,1);
			Collector.AddObject(pObject);
		}
	}

	music = Mix_LoadMUS( "bg.mp3" );
	if( music == NULL ) 
		return 6;
		
	//Timer used to update the caption 	
	Timer update;	
	Timer delta;	
	update.start();	
	Timer fps_counter;	
	fps_counter.start();	
	screen->frame = 0;	
	fps.start();
	while(quit == false)
	{
		if( update.get_ticks() > UPDATE_FREQUENCY )		
		{			
			//The frame rate as a string 			
			char caption[64]; 			
			memset(caption,0,64);	
			//Calculate the frames per second and create the string 			
			sprintf_s(caption,64,"STICKMAN - CAN'T BREATH - Average Frames Per Second: %.2f\0",(screen->frame / ( (double)fps_counter.get_ticks() / UPDATE_FREQUENCY ))* (1000 / UPDATE_FREQUENCY) );	
			//Reset the caption 			
			SDL_WM_SetCaption( caption, NULL ); 
			//Restart the update timer 			
			update.start(); 			
			screen->frame = 0;			
			fps_counter.start();		
		}
		if( ( cap == true ) && ( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) ) 		
		{ 
			//Sleep the remaining frame time. works fine but takes a shit ton more of cpu time. so ye 			
			//SDL_Delay(( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); 
			//reset timer
			//fps.start();	
			SDL_Delay(1);
			continue;
		}
#ifdef OGL_MODE
		glClearColor( 1, 1, 1, 1 );
		glClear( GL_COLOR_BUFFER_BIT );
		glLoadIdentity();
#endif
		//time to draw a frame
		fps.start();
		Collector.UpdateObjects();	
		screen->frame++;
		if(SDL_PollEvent( &event ))
		{
			p1->handle_events(event);
			//p2->handle_events(event);
			switch(event.type)
			{
				default:
				case SDL_KEYUP:
					break;
				case SDL_KEYDOWN:
					if(event.key.keysym.sym == SDLK_ESCAPE)
					{
						quit = true;
						break;
					}
					if( event.key.keysym.sym == SDLK_RETURN )
						if(cap)
						{
							cap = false;
#ifdef OGL_MODE
							//disable vsync in OGL which locks the framerate.
							typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
							PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
							const GLubyte *extensions = glGetString( GL_EXTENSIONS );				
							if( strstr( (char*)extensions, "WGL_EXT_swap_control" ) == 0 )
								printf("WGL_EXT_swap_control extension not supported on your computer.\n");
							else
							{
								wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
								if( wglSwapIntervalEXT )
								wglSwapIntervalEXT(0);
							}
#endif
						}
						else
						{
							cap = true;
#ifdef OGL_MODE
							//enable vsync in OGL which locks the framerate.
							typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
							PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
							const GLubyte *extensions = glGetString( GL_EXTENSIONS );				
							if( strstr( (char*)extensions, "WGL_EXT_swap_control" ) == 0 )
								printf("WGL_EXT_swap_control extension not supported on your computer.\n");
							else
							{
								wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
								if( wglSwapIntervalEXT )
								wglSwapIntervalEXT(1);
							}
#endif
						}
					if( event.key.keysym.sym == SDLK_BACKSPACE )
					{
						if(_log)
							_log = false;
						else
						{
							gprintf("------> enabled collision debug output\n"); 
							_log = true;
						}
					}
					break;
				case SDL_QUIT:
					quit = true; 
					break;
				/*case SDL_VIDEORESIZE:
					video.SCREEN_HEIGHT = event.resize.h;
					video.SCREEN_WIDTH = event.resize.w;
					zoomY = (double)video.SCREEN_HEIGHT / background->h;
					zoomX = (double)video.SCREEN_WIDTH / background->w;
					resize = true;
					break;*/
			}
		}	
		//If there is no music playing 
		/*if( music != NULL &&Mix_PlayingMusic() == 0 ) 
		{ 
			//Play the music 
			if( Mix_PlayMusic( music, -1 ) == -1 ) 
			quit = true;
		}*/
	}
	//Quit SDL
	//Free the music 
	if(music)
		Mix_FreeMusic( music ); 	//Quit SDL_mixer 
	Mix_CloseAudio();
	SDL_Quit(); 
	return 8; 
}